#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/times.h>
#include <sys/stat.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>

#include "fpdevice.h"
#include "fprotocol.h"

/*---------------------- command define----------------------*/
#define    	GET_IMAGE				0x01//
#define    	GEN_CHAR				0x02//
#define    	MATCH					0x03//
#define    	SEARCH			    	0x04//
#define    	REG_MODULE				0x05//
#define    	STORE_CHAR				0x06//
#define    	LOAD_CHAR				0x07//
#define    	UP_CHAR					0x08//
#define    	DOWN_CHAR				0x09//
#define    	UP_IMAGE		    	0x0a//
#define    	DOWN_IMAGE				0x0b//
#define    	DEL_CHAR		    	0x0c//
#define    	EMPTY 		      		0x0d//
#define		WRITE_REG				0x0e//
#define     READ_PAR_TABLE  		0x0f//
#define     ENROLL          		0x10//
#define     IDENTIFY        		0x11//
#define    	SET_PWD					0x12//
#define    	VFY_PWD					0x13//
#define     GET_RANDOM      		0x14//
#define     SET_CHIPADDR    		0x15//
#define     READ_INFPAGE    		0x16//
#define    	PORT_CONTROL			0x17//
#define    	WRITE_NOTEPAD   		0x18//
#define    	READ_NOTEPAD 			0x19//
#define     BURN_CODE       		0x1a//
#define     HIGH_SPEED_SEARCH   	0x1b//
#define     GEN_BINIMAGE        	0x1c//
#define     TEMPLATE_NUM        	0x1d
#define		GETIMAGEX				0x30	//
#define		UPIMAGEX				0x31	//
#define 	GENCHAREX				0x32

#define     REG_BAUD            	4//
#define    	REG_SECURE_LEVEL		5//
#define		REG_PACKETSIZE			6//

const unsigned char     CMD      =  0x01;  //
const unsigned char     DATA     =  0x02;  //
const unsigned char     ENDDATA  =  0x08;  //
const unsigned char     RESPONSE =  0x07;  //

const DWORD PACKET_HEAD = 0xEF01;//
const int   MAX_PACKAGE_SIZE  =  350;   //
const int   HEAD_LENGTH       =  3;     //
const int   TIMEOUT           =  100;   //
#define   APP_TIME_OUT      (30)  //

static char      g_sErrorString[128];    //
static int       g_nPackageSize = 128;   //
 
int GetTickCount()
{
	return times(NULL);
} 

void SetDeviceReset(BOOL reset)
{ 
}

BOOL EnCode(int nAddr,unsigned char* pSource, int iSourceLength, unsigned char* pDestination, int* iDestinationLength)
{
	unsigned char* pSrc;
	unsigned char* pDest;
	int i, count;
	int ChkSum,ValH,ValL;

	*iDestinationLength = 0;
	if ( !pSource || !pDestination )
		return FALSE;
	if ( iSourceLength > MAX_PACKAGE_SIZE-4 )  //閿熸枻鎷峰幓閿熸枻鎷峰ご閿熸枻鎷锋牎閿熸枻鎷烽敓鏂ゆ嫹
		return FALSE;

	pSrc = pSource;
	pDest = pDestination;

	*pDest++ = 0xEF;      
	*pDest++=0x01;
	*pDest++=(nAddr>>24)&0xff;
	*pDest++=(nAddr>>16)&0xff;
	*pDest++=(nAddr>>8)&0xff;
	*pDest++=nAddr&0xff;
 
 
	i = 0;
	count = 1;
	ChkSum=0;

	for (i=0; i<iSourceLength-2; i++)
	{
		 ChkSum+=*(pSrc+i);
		 *pDest++=*(pSrc+i);
	}
    ValL=ChkSum&0xff;
	ValH=(ChkSum>>8)&0xff;
    *pDest++=ValH;
	*pDest++=ValL;

	*iDestinationLength = iSourceLength+6;

	return TRUE;
}

BOOL DeCode(unsigned char* pSource, int iSourceLength, unsigned char* pDestination, int* iDestinationLength)
{
	unsigned char*   pSrc;
	unsigned char*   pDest;
    int ChkSum,ValH,ValL,Val,i;

	*iDestinationLength = 0;
	if ( !pSource || !pDestination)
		return FALSE;
    if ( iSourceLength<0 || iSourceLength>MAX_PACKAGE_SIZE )
		return FALSE;

	
	pSrc  = pSource;
	pDest = pDestination;

	if(*pSrc!=0xEF || *(pSrc+1)!=0x01) return FALSE;
    
	pSrc=pSource+6;

	ChkSum=0;

	for(i=0;i<(iSourceLength-8);i++)
	{
		*(pDest+i)=*(pSrc+i);
		ChkSum+=(unsigned char)(*(pSrc+i));
	}
	
	ValH=*(pSource+iSourceLength-2);
	ValL=*(pSource+iSourceLength-1);
    Val=(ValH<<8)+ValL;

	if(ChkSum!=Val) 
		return FALSE; 

	*iDestinationLength = iSourceLength-8;

	return TRUE;
}

BOOL GetPackageCom(unsigned char *pData,int nTimeOut/*=APP_TIME_OUT*/)
{   
	int i,PacketLen,RecNum;
    unsigned char cChar;
	unsigned char headerBuf[10];
	unsigned char recvBuf[MAX_PACKAGE_SIZE];
	unsigned char* decodedBuf;
	int           nCount;
	int           nDecodedLen;
	BOOL          bSuccess = FALSE;
    long          checkSum = 0;
	int           nRepeatTime = 0;
	DWORD         dwStart, dwStop;
	//	COMSTAT  comstat;
	DWORD    dwError;
    
	if (!pData)
		return FALSE;
	decodedBuf = pData;
	for(i=0;i<10;i++)
		headerBuf[i]=0;
	RecNum=0;
	dwStart = GetTickCount();
 	while (1)
	{
		bSuccess = GetByte(&cChar);
		if(bSuccess)
		{
			for(i=0;i<8;i++)
				headerBuf[i]=headerBuf[i+1];
			headerBuf[8]=cChar;
			if((headerBuf[0]==0xef)&&(headerBuf[1]==0x01))
				break;
		}
		dwStop = GetTickCount();
		if ( dwStop-dwStart > nTimeOut )
		{
			//ClearCommError(g_hCom, &dwError, &comstat);
			return FALSE;
		}
	}

	PacketLen=0;
	for(nCount=0;nCount<9;nCount++)
		recvBuf[nCount]=headerBuf[nCount];
	PacketLen=(recvBuf[7]<<8)+recvBuf[8];
	dwStart = GetTickCount();
	while (1)
	{
		if ( !GetByte(&cChar) )
			continue;
		recvBuf[nCount++] = cChar;
		if((PacketLen>0) && (nCount>=PacketLen+9))
			break;
		dwStop = GetTickCount();
		if ( dwStop-dwStart > nTimeOut )
		{
			//ClearCommError(g_hCom, &dwError, &comstat);
			return FALSE;
		}
	}
	if ( !DeCode(recvBuf, nCount, decodedBuf, &nDecodedLen) )
		return FALSE;
	return TRUE;
} 

BOOL GetPackage(unsigned char *pData,int nLen/*=64*/,int nTimeOut/*=APP_TIME_OUT*/)
{
	//usleep(100);
	return GetPackageCom(pData,nTimeOut);
}

BOOL GetPackageX(unsigned char *pData,int nLen/*=64*/,int nTimeOut/*=APP_TIME_OUT*/)
{
	usleep(50);
	return GetPackageCom(pData,nTimeOut);
}

int GetPackageLength(unsigned char* pData)
{
	int length = 0;
	if (!pData)
		return 0;	
	length = pData[1]*256 + pData[2] + 1 +2;
	return length;
}

int GetPackageContentLength(unsigned char* pData)
{
	int length = 0;
	if (!pData)
		return 0;	
	length = pData[1]*256 + pData[2];
	return length;
}

BOOL SendPackageCom(int nAddr,unsigned char *pData)
{   
	int iLength,i;
	int iEncodedLength;
	unsigned char encodedBuf[MAX_PACKAGE_SIZE+20];
	BOOL bSuccess = FALSE;
	DWORD    dwError;

	if (!pData)
		return FALSE;
        ClearCom();
 
	iLength = GetPackageLength(pData);
	if (iLength>MAX_PACKAGE_SIZE)
		return FALSE;
	if ( !EnCode(nAddr,pData, iLength, encodedBuf, &iEncodedLength) )
		return FALSE;
	if (iEncodedLength > MAX_PACKAGE_SIZE)
		return FALSE;

	/*
	if ( !ClearCommError(g_hCom, &dwError, &comstat) )
	{
		return FALSE;
	}
	*/
	for (i=0; i<iEncodedLength; i++)
	{
		if ( !SendByte(encodedBuf[i]) ) 
			return FALSE;
	} 
	return TRUE;
}

BOOL SendPackage(int nAddr,unsigned char*pData)
{
	usleep(1*1000);
	return SendPackageCom(nAddr,pData);
}

int FillPackage(unsigned char* pData, int nPackageType, int nLength, unsigned char* pContent)
{
	int totalLen = 0;
	long checksum = 0;
 
	if (!pData || nLength<0 || nLength>MAX_PACKAGE_SIZE )
		return 0;
	if ( (nPackageType != CMD) && (nPackageType != DATA) && (nPackageType != ENDDATA) )
		return 0;
    nLength+=2;
	pData[0] = nPackageType;
	pData[1] = (nLength>>8) & 0xff;
	pData[2] = nLength & 0xff;
	if (nLength)
	{
		if (!pContent)
			return 0;
		memcpy(pData+3, pContent, nLength);
	}
	totalLen = nLength + 3;  
	return totalLen;
}

int VerifyResponsePackage(unsigned char nPackageType, unsigned char* pData)
{
	long checkSum = 0;
	if (!pData)
		return -3;
	if ( pData[0] != nPackageType )
		return -3;
	int iLength;
	iLength = GetPackageLength(pData);
	if (nPackageType == RESPONSE)
		return pData[3];
	return 0;
}

int WriteBMP(char* file,unsigned char* Input,int width,int height)
{
	unsigned char head[1078]={
		/***************************/
		//file header
	    	0x42,0x4d,//file type 
			//0x36,0x6c,0x01,0x00, //file size***
			0x0,0x0,0x0,0x00, //file size***
			0x00,0x00, //reserved
			0x00,0x00,//reserved
			0x36,0x4,0x00,0x00,//head byte***
			/***************************/
			//infoheader
			0x28,0x00,0x00,0x00,//struct size
			
			//0x00,0x01,0x00,0x00,//map width*** 
			0x00,0x00,0x0,0x00,//map width*** 
			//0x68,0x01,0x00,0x00,//map height***
			0x00,0x00,0x00,0x00,//map height***
			
			0x01,0x00,//must be 1
			0x08,0x00,//color count***
			0x00,0x00,0x00,0x00, //compression
			//0x00,0x68,0x01,0x00,//data size***
			0x00,0x00,0x00,0x00,//data size***
			0x00,0x00,0x00,0x00, //dpix
			0x00,0x00,0x00,0x00, //dpiy
			0x00,0x00,0x00,0x00,//color used
			0x00,0x00,0x00,0x00,//color important
			
	};
	
	FILE *fh;
	if( (fh  = fopen( file, "wb" )) == NULL )
           return 0;
 	int i,j;
	long num;
	num=width; head[18]= num & 0xFF;
	num=num>>8;  head[19]= num & 0xFF;
	num=num>>8;  head[20]= num & 0xFF;
	num=num>>8;  head[21]= num & 0xFF;
	num=height; head[22]= num & 0xFF;
	num=num>>8;  head[23]= num & 0xFF;
	num=num>>8;  head[24]= num & 0xFF;
	num=num>>8;  head[25]= num & 0xFF;
	j=0;
	for (i=54;i<1078;i=i+4)
	{
		head[i]=head[i+1]=head[i+2]=j; 
		head[i+3]=0;
		j++;
	}
 	fwrite(head,sizeof(char),1078,fh);
 	fwrite(Input,1,width*height,fh); 
	fclose(fh);
	return 1;
}

void Delay(int nTimes)
{
	dDelay(nTimes);
}

BOOL GetDataFromBMP(const char* pFileName, unsigned char* pImageData)
{
	int num = 0;
	int nFileLength = 0;
	FILE* fp;
	if ( (fp = fopen(pFileName, "rb")) == NULL )
		return FALSE;
	fseek(fp, 1078, SEEK_SET);
	nFileLength = fread(pImageData, sizeof(char), IMAGE_X*IMAGE_Y, fp);
	fclose(fp);
	if ( nFileLength <IMAGE_X*IMAGE_Y)
		return FALSE;	
	return TRUE;
}

int PSOpenDevice(int nDeviceType,int nPortNum,int nPortPara,int nPackageSize)
{
	switch(nPackageSize)
	{	 
		case 0:
			g_nPackageSize=32;
			break;
		case 1:
			g_nPackageSize=64;
			break;
		case 2:
			g_nPackageSize=128;
			break;
		case 3:
			g_nPackageSize=256;
			break;
		default:g_nPackageSize=128;
	}
   return OpenCom(nPortNum,nPortPara);
}

BOOL PSCloseDevice()
{
	return CloseCom();
}

int PSGetImage(int nAddr)
{
	int num;
	unsigned char cCmd[10];
	int result;
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);

	cCmd[0] = GET_IMAGE;
    num = FillPackage(iSendData, CMD, 1, cCmd);
	if( !SendPackage(nAddr,iSendData) ) 
		return -1;
        
	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;

	result = VerifyResponsePackage(RESPONSE, iGetData);
	return result;
}

int   PSGenChar(int nAddr,int iBufferID)
{
	unsigned char cCmd[10];
	int num;
	int result;
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);

	cCmd[0] = GEN_CHAR;
	cCmd[1] = iBufferID;
    num = FillPackage(iSendData, CMD, 2, cCmd);
	if( !SendPackage(nAddr,iSendData) ) 
		return -1;
	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;

	result = VerifyResponsePackage(RESPONSE, iGetData);
	return result;
} 

int   PSMatch(int nAddr,int* iScore)
{
	unsigned char cCmd[10];
	int num;
	int result;
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);

	cCmd[0] = MATCH;
    num = FillPackage(iSendData, CMD, 1, cCmd);
	if( !SendPackage(nAddr,iSendData) ) 
		return -1;
	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;

	result = VerifyResponsePackage(RESPONSE, iGetData);

	if (iScore!=NULL)
	{
		*iScore = iGetData[HEAD_LENGTH+1]<<8;
		*iScore |= iGetData[HEAD_LENGTH+2];
	}
	return result;
}

int   PSSearch(int nAddr,int iBufferID, int iStartPage, int iPageNum, int *iMbAddress)
{
	unsigned char cContent[10];
	int num;
	int result;
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);

	if( (iBufferID<1) || (iBufferID>3) ||(iStartPage<0) || (iPageNum<0) )
		return -4;

	cContent[0] = SEARCH;
	cContent[1] = iBufferID;
	cContent[2] = (iStartPage>>8) & 0xff;  
	cContent[3] = iStartPage & 0xff;
	cContent[4] = (iPageNum>>8) & 0xff;
	cContent[5] = iPageNum & 0xff;

    num = FillPackage(iSendData, CMD, 6, cContent);

	if( !SendPackage(nAddr,iSendData) ) 
		return -1;
	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;

	result = VerifyResponsePackage(RESPONSE, iGetData);

	*iMbAddress = iGetData[HEAD_LENGTH+1]<<8;
	*iMbAddress |= iGetData[HEAD_LENGTH+2];
 
	return result;
}

int   PSHighSpeedSearch(int nAddr,int iBufferID, int iStartPage, int iPageNum, int *iMbAddress)
{
	unsigned char cContent[10];
	int num;
	int result;
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);
	
	if( (iBufferID<1) || (iBufferID>3) ||(iStartPage<0) || (iPageNum<0) )
		return -4;
	
	cContent[0] = HIGH_SPEED_SEARCH;
	cContent[1] = iBufferID;
	cContent[2] = (iStartPage>>8) & 0xff;  
	cContent[3] = iStartPage & 0xff;
	cContent[4] = (iPageNum>>8) & 0xff;
	cContent[5] = iPageNum & 0xff;
	
    num = FillPackage(iSendData, CMD, 6, cContent);
	
	if( !SendPackage(nAddr,iSendData) ) 
		return -1;
	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;
	
	result = VerifyResponsePackage(RESPONSE, iGetData);
	
	*iMbAddress = iGetData[HEAD_LENGTH+1]<<8;
	*iMbAddress |= iGetData[HEAD_LENGTH+2];
	
	return result;
}

int   PSRegModule(int nAddr)
{
	int num;
	int result;
	unsigned char cCmd[10];
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);

	cCmd[0] = REG_MODULE;

    num = FillPackage(iSendData, CMD, 1, cCmd);

	if( !SendPackage(nAddr,iSendData) ) 
		return -1;
	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;

	result = VerifyResponsePackage(RESPONSE, iGetData);
	return result;
}

int   PSStoreChar(int nAddr,int iBufferID, int iPageID)
{
	int num;
	int result;
	unsigned char cContent[10];
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);

	if( (iBufferID<1) || (iBufferID>3) || (iPageID<0) )
		return -4;

	cContent[0] = STORE_CHAR;
	cContent[1] = iBufferID;   
	cContent[2] = (iPageID>>8) & 0xff;
	cContent[3] = iPageID & 0xff;  

    num = FillPackage(iSendData, CMD, 4, cContent);

	if( !SendPackage(nAddr,iSendData) ) 
		return -1;
	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;

	result = VerifyResponsePackage(RESPONSE, iGetData);

	return result;
}	

int   PSLoadChar(int nAddr,int iBufferID,int iPageID)
{
	int num;
	int result;
	unsigned char cContent[10];
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);

	if( (iBufferID<1) || (iBufferID>3) || (iPageID<0) )
		return -4;

	cContent[0] = LOAD_CHAR;
	cContent[1] = iBufferID;
	cContent[2] = (iPageID>>8) & 0xff;
	cContent[3] = iPageID & 0xff;  

    num = FillPackage(iSendData, CMD, 4, cContent);

	if( !SendPackage(nAddr,iSendData) ) 
		return -1;
	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;

	result = VerifyResponsePackage(RESPONSE, iGetData);

	return result;
}

int   PSUpChar(int nAddr,int iBufferID, unsigned char* pTemplet, int* iTempletLength)
{
	int num;
	int result;
	unsigned char cContent[10];
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);

	if( (iBufferID<1) || (iBufferID>3) || !pTemplet || !iTempletLength )
		return -4;

	cContent[0] = UP_CHAR;
	cContent[1] = iBufferID;

    num = FillPackage(iSendData, CMD, 2, cContent);

	if( !SendPackage(nAddr,iSendData) ) 
		return -1;

	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;

	result = VerifyResponsePackage(RESPONSE, iGetData);

	if ( result != 0 )
	    return result;

	int length;
	int totalLen = 0;
	int checkResult = 0;
	DWORD         dwStart, dwStop;
	
	dwStart = GetTickCount();
	do
	{
		memset(iGetData, 0, MAX_PACKAGE_SIZE);
	    if ( !GetPackage(iGetData,64,APP_TIME_OUT) )
		    return -2;

	    length = GetPackageContentLength(iGetData)-2;
		result = VerifyResponsePackage(iGetData[0], iGetData);
		if ( result != 0 )
			checkResult = -3;

	    memcpy((void*)(pTemplet+totalLen), (void*)(iGetData+HEAD_LENGTH), length);
		
		totalLen += length;

		dwStop = GetTickCount();
		if ( (dwStop-dwStart) > APP_TIME_OUT )
			return -2;
	}
	while ( iGetData[0] != ENDDATA );
	
	*iTempletLength = totalLen;

	if ( *iTempletLength == 0 )
		return -2;

	return checkResult;
}

int   PSDownChar(int nAddr,int iBufferID, unsigned char* pTemplet, int iTempletLength)
{
	int num;
	int result;
	unsigned char cContent[10];
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);

	if( (iBufferID<1) || (iBufferID>3) || !pTemplet || (iTempletLength<=0) )
		return -4;

	cContent[0] = DOWN_CHAR;
	cContent[1] = iBufferID;

    num = FillPackage(iSendData, CMD, 2, cContent);

	if( !SendPackage(nAddr,iSendData) ) 
		return -1;


	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;

	result = VerifyResponsePackage(RESPONSE, iGetData);

	if ( result != 0 )
	    return result;

	int totalLen = iTempletLength;
	unsigned char* pData = pTemplet;

	while (totalLen > g_nPackageSize)
	{
		memset(iSendData, 0, MAX_PACKAGE_SIZE);
	    num = FillPackage(iSendData, DATA, g_nPackageSize, pData);

		pData += g_nPackageSize;
		totalLen -= g_nPackageSize;

	    if ( !SendPackage(nAddr,iSendData) )
		    return -1;
	}
	
	memset(iSendData, 0, MAX_PACKAGE_SIZE);
    num = FillPackage(iSendData, ENDDATA, totalLen, pData);

    if ( !SendPackage(nAddr,iSendData) )
	    return -1;
	
	return 0;
}

int   PSUpChar2File(int nAddr,int iBufferID, const char* pFileName)
{
	unsigned char pTemplate[2048];
	int nFileLength = 0;
	int result;
	
	memset(pTemplate, 0, 2048);
	result = PSUpChar(nAddr,iBufferID, pTemplate, &nFileLength);
	if (result!=0)
		return result;

	FILE* fp;
	if ( (fp = fopen(pFileName, "wb")) == NULL )
		return -6;

	if ( (result = fwrite(pTemplate, 1, nFileLength, fp)) != nFileLength )
	{
		fclose(fp);
		return -8;
	}

	fclose(fp);

	return 0;
}

int   PSDownCharFromFile(int nAddr,int iBufferID, const char* pFileName)
{
	unsigned char pTemplate[2048];
	int nFileLength = 0;
	int result;
	int num = 0;
	
	memset(pTemplate, 0, 2048);

	FILE* fp;
	if ( (fp = fopen(pFileName, "rb")) == NULL )
		return -7;

	while ( !feof(fp) ) 
	{
		num = fread(pTemplate+nFileLength, sizeof(char), 1024, fp);
		nFileLength += num;
	}
	fclose(fp);

	result = PSDownChar(nAddr,iBufferID, pTemplate, nFileLength);

	return result;
} 

int   PSUpImage(int nAddr,unsigned char* pImageData, int* iImageLength)
{
	int num,i;
	int result;
	unsigned char cCmd[10];
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	BYTE pImageTemp[IMAGE_Y*IMAGE_X];  
	
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);

	if( !pImageData )
		return -1;

	cCmd[0] = UP_IMAGE;

    num = FillPackage(iSendData, CMD, 1, cCmd);
		
	if( !SendPackage(nAddr,iSendData) ) 
		return -1;

	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;

	result = VerifyResponsePackage(RESPONSE, iGetData);

	if ( result != 0 )
	    return result;

	int length;
	int totalLen = 0;
	int checkResult = 0;
	int PacketNum=0;

	DWORD dwStart, dwStop;
	DWORD dwError;
	do
	{
		memset(iGetData, 0, MAX_PACKAGE_SIZE);
	    if ( !GetPackageX(iGetData,64,APP_TIME_OUT) )
		    return -2;

	    length = GetPackageContentLength(iGetData)-2;
		result = VerifyResponsePackage(iGetData[0], iGetData);
		if ( result != 0 )
			checkResult = -2;

	     memcpy((void*)(pImageData+totalLen), (void*)(iGetData+HEAD_LENGTH), length);
		totalLen += length;
		PacketNum++;
	}
	while ( iGetData[0] != ENDDATA );

	for(i=0;i<IMAGE_X*IMAGE_Y/2;i++)
	{
		  pImageTemp[i*2]=(*(pImageData+i)>>4)*16;
		  pImageTemp[i*2+1]=(*(pImageData+i)&0x0f)*16;
	}
	*iImageLength = totalLen*2;
	memcpy(pImageData,pImageTemp,IMAGE_X*IMAGE_Y);
    return checkResult;
}	

int   PSGetImgDataFromBMP(const char *pImageFile,unsigned char *pImageData,int *pnImageLen)
{
	int i,n;
    unsigned char* pData;
	unsigned char*pNewData;
	pData=malloc(IMAGE_X*IMAGE_Y);
	pNewData=malloc(IMAGE_X*IMAGE_Y);
	 
	
	BOOL ret = GetDataFromBMP(pImageFile, pData);
	if (!ret)
	{
		free(pData);
		free(pNewData);
		return -7;
	}
	for(n=0;n<IMAGE_Y;n++)
	{
		memcpy(pNewData+n*IMAGE_X,pData+(IMAGE_Y-1-n)*IMAGE_X,IMAGE_X);
	}

	for(i=0;i<IMAGE_Y*IMAGE_X/2;i++)
	{
		*(pImageData+i)=(((pNewData[2*i]/16)<<4)&0xf0)+((pNewData[2*i+1]/16)&0x0f);
	}

	*pnImageLen = IMAGE_Y*IMAGE_X/2; 
	free(pData);
	free(pNewData);
	return 0;
}

int   PSImgData2BMP(unsigned char* pImgData,const char* pImageFile,int width,int height)
{
	int i;
	unsigned char newData[IMAGE_X*IMAGE_Y]; 

	for(i=0;i<IMAGE_X*IMAGE_Y/2;i++)
	{
		newData[i*2]=(*(pImgData+i)>>4)*16;
		newData[i*2+1]=(*(pImgData+i)&0x0f)*16;
	}

	BOOL ret = WriteBMP((char*)pImageFile, newData,width,height);

	 
	if ( !ret )
		return -6;

	return 0;
}

int   PSDownImage(int nAddr,unsigned char *pImageData, int iLength)
{
	int num,n;
	int result;
	unsigned char cCmd[10];
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
        unsigned char pNewData[IMAGE_X*IMAGE_Y];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);

	if( !pImageData )
		return -2;

	cCmd[0] = DOWN_IMAGE;

    num = FillPackage(iSendData, CMD, 1, cCmd);

	if( !SendPackage(nAddr,iSendData) ) 
		return -1;

	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;

	result = VerifyResponsePackage(RESPONSE, iGetData);

	if ( result != 0 )
	    return result;

 


	int totalLen = iLength;
	unsigned char* pData = pImageData;

	while (totalLen > g_nPackageSize)
	{
		memset(iSendData, 0, MAX_PACKAGE_SIZE);
	    num = FillPackage(iSendData, DATA, g_nPackageSize, pData);

		pData += g_nPackageSize;
		totalLen -= g_nPackageSize;

	    if ( !SendPackage(nAddr,iSendData) )
		    return -1;
	}

	

	memset(iSendData, 0, MAX_PACKAGE_SIZE);
    num = FillPackage(iSendData, ENDDATA, totalLen, pData);

    if ( !SendPackage(nAddr,iSendData) )
	    return -1;
	
	return 0;
}

int   PSDelChar(int nAddr,int iStartPageID,int nDelPageNum)
{
	int num;
	int result;
	unsigned char cContent[10];
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);

	if((iStartPageID<0) || nDelPageNum<=0)
		return -4;

	cContent[0] = DEL_CHAR;
	cContent[1] = (iStartPageID>>8) & 0xff;
	cContent[2] = iStartPageID & 0xff;  
	cContent[3] = (nDelPageNum>>8) &0xff;
	cContent[4] = nDelPageNum & 0xff;

    num = FillPackage(iSendData, CMD, 5, cContent);

	if( !SendPackage(nAddr,iSendData) ) 
		return -1;
	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;

	result = VerifyResponsePackage(RESPONSE, iGetData);

	return result;
}

int   PSEmpty(int nAddr)
{
	int num;
	int result;
	unsigned char cCmd[10];
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);

	cCmd[0] = EMPTY;  

    num = FillPackage(iSendData, CMD, 1, cCmd);

	if( !SendPackage(nAddr,iSendData) ) 
		return -1;
	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;

	result = VerifyResponsePackage(RESPONSE, iGetData);

	return result;
}


int   PSReadParTable(int nAddr,unsigned char* pParTable)
{
	int num;
	int result;
	unsigned char cCmd[10];
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);

	if (!pParTable)
		return -2;

	cCmd[0] = READ_PAR_TABLE;  

    num = FillPackage(iSendData, CMD, 1, cCmd);

	if( !SendPackage(nAddr,iSendData) ) 
		return -1;
	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;

	result = VerifyResponsePackage(RESPONSE, iGetData);

	if ( result != 0 )
		return result;

	memcpy((void*)pParTable, (void*)(iGetData+HEAD_LENGTH+1), 16);  //閿熸枻鎷烽敓鏂ゆ嫹閿熸枻鎷�6閿熻鏂ゆ嫹

    return 0;
}
 
 
int   PSEnroll(int nAddr,int* nID)
{
	int num;
	int result;
	unsigned char cCmd[10];
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);

	cCmd[0] = ENROLL;  

    num = FillPackage(iSendData, CMD, 1, cCmd);

	if( !SendPackage(nAddr,iSendData) ) 
		return -1;
	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;

	result = VerifyResponsePackage(RESPONSE, iGetData);
	*nID = iGetData[HEAD_LENGTH+1]<<8;
	*nID |= iGetData[HEAD_LENGTH+2];
 

    return result;
}
 

int   PSSetPwd(int nAddr,unsigned char* pPassword)
{
	int num;
	int result;
	unsigned char cContent[10];
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);

	cContent[0] = SET_PWD;
	cContent[1] = pPassword[0];
	cContent[2] = pPassword[1];
	cContent[3] = pPassword[2];
	cContent[4] = pPassword[3];

    num = FillPackage(iSendData, CMD, 5, cContent);

	if( !SendPackage(nAddr,iSendData) ) 
		return -1;
	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;

	result = VerifyResponsePackage(RESPONSE, iGetData);

	return result;
}

int  PSVfyPwd(int nAddr,unsigned char* pPassword)
{
	int num;
	int result;
	unsigned char cContent[10];
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);

	cContent[0] = VFY_PWD;
	cContent[1] = pPassword[0];
	cContent[2] = pPassword[1];
	cContent[3] = pPassword[2];
	cContent[4] = pPassword[3];

    num = FillPackage(iSendData, CMD, 5, cContent);

	if( !SendPackage(nAddr,iSendData) ) 
		return -1;
	if( !GetPackage(iGetData,64,1000) )  
		return -2;


	result = VerifyResponsePackage(RESPONSE, iGetData);

	return result;
}	


int   PSIdentify(int nAddr,int *iMbAddress)
{
	int num;
	int result;
	unsigned char cCmd[10];
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);

	cCmd[0] = IDENTIFY;

    num = FillPackage(iSendData, CMD, 1, cCmd);

	if( !SendPackage(nAddr,iSendData) ) 
		return -1;
	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;

	result = VerifyResponsePackage(RESPONSE, iGetData);
	*iMbAddress = iGetData[HEAD_LENGTH+1]<<8;
	*iMbAddress |= iGetData[HEAD_LENGTH+2];

	return result;
}

int	 PSWriteInfo(int nAddr,int nPage,unsigned char* UserContent)
{
	int num;
	int result;
	unsigned char cContent[256];
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);
	
	if (!UserContent)
		return -1;
	
	memset(cContent, 0, 10);
	cContent[0] = WRITE_NOTEPAD;  
	cContent[1] = nPage;
	memcpy((void*)(cContent+2), (void*)UserContent, 32);  //閿熺煫浼欐嫹閿熸枻鎷锋伅32閿熸枻鎷烽敓琛楁枻鎷�

    num = FillPackage(iSendData, CMD, 34, cContent);
	
	if( !SendPackage(nAddr,iSendData) ) 
		return -1;
	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;
	
	result = VerifyResponsePackage(RESPONSE, iGetData);
	return result;

}

int	 PSReadInfo(int nAddr,int nPage,unsigned char* UserContent)
{
	int num;
	int result;
	unsigned char cContent[2];
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[1024];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);
	
	if (!UserContent)
		return -1;
	
	cContent[0] = READ_NOTEPAD;  
	cContent[1] = nPage; 
	
    num = FillPackage(iSendData, CMD, 2, cContent);
	
	if( !SendPackage(nAddr,iSendData) ) 
		return -1;
	if( !GetPackage(iGetData,512,APP_TIME_OUT) )  
		return -2;
	
	result = VerifyResponsePackage(RESPONSE, iGetData);
	if(result!=0)
		return result;
	memcpy(UserContent,&iGetData[HEAD_LENGTH+1],32);
	return result;

}

int   PSWriteReg(int nAddr,int iRegAddr,int iRegValue)
{
	int num;
	int result;
	unsigned char cContent[10];
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);

	cContent[0] = WRITE_REG;
	cContent[1] = iRegAddr;
	cContent[2] = iRegValue;

    num = FillPackage(iSendData, CMD, 3, cContent);

	if( !SendPackage(nAddr,iSendData) ) 
		return -1;
	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;

	result = VerifyResponsePackage(RESPONSE, iGetData);

	return result;
}

int PSSetBaud(int nAddr,int nBaudNum)
{
	return PSWriteReg(nAddr,REG_BAUD,nBaudNum);
}

int PSSetSecurLevel(int nAddr,int nLevel)
{
	return PSWriteReg(nAddr,REG_SECURE_LEVEL,nLevel);
}

int PSSetPacketSize(int nAddr,int nSize)
{
	int nRet=PSWriteReg(nAddr,REG_PACKETSIZE,nSize);
	if(nRet==0)
	{
		switch(nSize) {
		case 0:
			g_nPackageSize=32;
			break;
		case 1:
			g_nPackageSize=64;
			break;
		case 2:
			g_nPackageSize=128;
			break;
		case 3:
			g_nPackageSize=256;
			break;
		default:g_nPackageSize=128;
		}
	}
	return nRet;

}

int PSGetRandomData(int nAddr,unsigned char* pRandom)
{
	int num;
	int result;
	unsigned char cContent[2];
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);
	
	if (!pRandom)
		return -1;
	
	cContent[0] = GET_RANDOM;  
	
    num = FillPackage(iSendData, CMD, 1, cContent);
	
	if( !SendPackage(nAddr,iSendData) ) 
		return -1;
	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;
	
	result = VerifyResponsePackage(RESPONSE, iGetData);
	if(result!=0)
		return result;
	memcpy(pRandom,&iGetData[HEAD_LENGTH+1],4);
	return result;
}

int PSSetChipAddr(int nAddr,unsigned char* pChipAddr)
{
	int num;
	int result;
	unsigned char cContent[10];
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);
	
	cContent[0] = SET_CHIPADDR;
	cContent[1] = pChipAddr[0];
	cContent[2] = pChipAddr[1];
	cContent[3] = pChipAddr[2];
	cContent[4] = pChipAddr[3];
	
    num = FillPackage(iSendData, CMD, 5, cContent);
	
	if( !SendPackage(nAddr,iSendData) ) 
		return -1;
	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;
	
	result = VerifyResponsePackage(RESPONSE, iGetData);
	
	return result;
}

int PSPortControl(int nAddr,BOOL bOpen)
{
	int num;
	int result;
	unsigned char cContent[10];
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);
	
	cContent[0] = PORT_CONTROL;
	cContent[1] = bOpen;
 
	
    num = FillPackage(iSendData, CMD, 2, cContent);
	
	if( !SendPackage(nAddr,iSendData) ) 
		return -1;
	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;
	
	result = VerifyResponsePackage(RESPONSE, iGetData);
	
	return result;
}

int   PSReadInfPage(int nAddr, unsigned char* pInf)
{
	int num;
	int result;
	unsigned char cContent[10];
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);
	
 
	cContent[0] = READ_INFPAGE;
 
	
    num = FillPackage(iSendData, CMD, 1, cContent);
	
	if( !SendPackage(nAddr,iSendData) ) 
		return -1;
	
	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;
	
	result = VerifyResponsePackage(RESPONSE, iGetData);
	
	if ( result != 0 )
		return result;


	int length;
	int totalLen = 0;
	int checkResult = 0;
	int dwStart, dwStop;
	
	dwStart = GetTickCount();
	do
	{
		memset(iGetData, 0, MAX_PACKAGE_SIZE);
		if ( !GetPackage(iGetData,64,APP_TIME_OUT) )
			return -2;
		
		length = GetPackageContentLength(iGetData)-2;
		result = VerifyResponsePackage(iGetData[0], iGetData);
		if ( result != 0 )
			checkResult = -3;
		
		memcpy((void*)(pInf+totalLen), (void*)(iGetData+HEAD_LENGTH), length);
		
		totalLen += length;
		
		dwStop = GetTickCount();
		if ( (dwStop-dwStart) > APP_TIME_OUT )
			return -2;
	}
	while ( iGetData[0] != ENDDATA );
	
 
	
	if ( totalLen == 0 )
		return -2;
	
	return checkResult;
}


int PSGenBinImage(int nAddr, int nImgType)
{
   	int num;
	int result;
	unsigned char cContent[10];
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);
 
	
	cContent[0] = GEN_BINIMAGE;
	cContent[1] = nImgType;
 
	
    num = FillPackage(iSendData, CMD, 2, cContent);
	
	if( !SendPackage(nAddr,iSendData) ) 
		return -1;
	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;
	
	result = VerifyResponsePackage(RESPONSE, iGetData);
	
	return result;
}

int   PSBurnCode(int nAddr,int nType,unsigned char *pImageData, int iLength)
{
	int num,i;
	int result;
        unsigned char Temp;
	unsigned char cCmd[10];
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE); 

	if( !pImageData )
		return -2; 

	cCmd[0] = BURN_CODE;
	cCmd[1] = nType;

    num = FillPackage(iSendData, CMD, 2, cCmd);

	if( !SendPackage(nAddr,iSendData) ) 
		return -1;

	 

	for(i=0;i<iLength/2;i++)
	{
		
		Temp=*(pImageData+i*2);
        *(pImageData+i*2)=*(pImageData+i*2+1);
		*(pImageData+i*2+1)=Temp;
	}

	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;

	result = VerifyResponsePackage(RESPONSE, iGetData);

	if ( result != 0  && result!=0xf0)
	    return result;

	int totalLen = iLength;
	unsigned char* pData = pImageData;

	while (totalLen > g_nPackageSize)
	{
		memset(iSendData, 0, MAX_PACKAGE_SIZE);
	    num = FillPackage(iSendData, DATA, g_nPackageSize, pData);

		pData += g_nPackageSize;
		totalLen -= g_nPackageSize;

	    if ( !SendPackage(nAddr,iSendData) )
		    return -1;
	}
	
	memset(iSendData, 0, MAX_PACKAGE_SIZE);
    num = FillPackage(iSendData, ENDDATA, totalLen, pData);

    if ( !SendPackage(nAddr,iSendData) )
	    return -1;
	
	return 0;
}

int   PSTemplateNum(int nAddr,int *iMbNum)
{
	int num;
	int result;
	unsigned char cCmd[10];
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);
	
	cCmd[0] = TEMPLATE_NUM;
	
    num = FillPackage(iSendData, CMD, 1, cCmd);
	
	if( !SendPackage(nAddr,iSendData) ) 
		return -1;
	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;
	
	result = VerifyResponsePackage(RESPONSE, iGetData);
	*iMbNum = iGetData[HEAD_LENGTH+1]<<8;
	*iMbNum |= iGetData[HEAD_LENGTH+2];
	
	return result;
}

int FPGetImageEx(int nAddr)
{
	int num;
	unsigned char cCmd[10];
	int result;
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);

	cCmd[0] = GETIMAGEX;

	num = FillPackage(iSendData, CMD, 1, cCmd);
	if( !SendPackage(nAddr,iSendData) ) 
		return -1;
	if( !GetPackage(iGetData,64,160000) )  
		return -2;

	result = VerifyResponsePackage(RESPONSE, iGetData);

	return result;
}

int FPUpImageEx(int nAddr,unsigned char* pImageData, int* iImageLength)
{
	int num,i;
	int result;
	unsigned char cCmd[10];
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	BYTE pImageTemp[IMAGE_Y*IMAGE_X]; 
	
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);

	if( !pImageData )
		return -1;
	
	cCmd[0] = UPIMAGEX;
    num = FillPackage(iSendData, CMD, 1, cCmd);
	if( !SendPackage(nAddr,iSendData) ) 
		return -1;
	if( !GetPackage(iGetData,64,APP_TIME_OUT) )  
		return -2;
	result = VerifyResponsePackage(RESPONSE, iGetData);
	if ( result != 0 )
		return result;
	
	int length;
	int totalLen = 0;
	int checkResult = 0;
	int PacketNum=0;

	do{
		memset(iGetData, 0, MAX_PACKAGE_SIZE);
		if ( !GetPackageX(iGetData,64,APP_TIME_OUT) )
			return -2;
		
		length = GetPackageContentLength(iGetData)-2;
		result = VerifyResponsePackage(iGetData[0], iGetData);
		if ( result != 0 )
			checkResult = -2;
		
		memcpy((void*)(pImageData+totalLen), (void*)(iGetData+HEAD_LENGTH), length);
		totalLen += length;
		PacketNum++;
	}
	while ( iGetData[0] != ENDDATA );

	for(i=0;i<OIMAGE_X*OIMAGE_Y/2;i++)
	{
		  pImageTemp[i*2]=(*(pImageData+i)>>4)*16;
		  pImageTemp[i*2+1]=(*(pImageData+i)&0x0f)*16;
	}
	
	*iImageLength = totalLen*2;
	memcpy(pImageData,pImageTemp,OIMAGE_X*OIMAGE_Y);
    return checkResult;
}

int   FPGenCharEx(int nAddr,int iBufferID)
{
	unsigned char cCmd[10];
	int num;
	int result;
	unsigned char iSendData[MAX_PACKAGE_SIZE], iGetData[MAX_PACKAGE_SIZE];
	memset(iSendData,0,MAX_PACKAGE_SIZE);
	memset(iGetData,0,MAX_PACKAGE_SIZE);

	cCmd[0] = GENCHAREX;
	cCmd[1] = iBufferID;
    num = FillPackage(iSendData, CMD, 2, cCmd);
	if( !SendPackage(nAddr,iSendData) )
		return -1;
	if( !GetPackage(iGetData,64,APP_TIME_OUT*10) )
		return -2;

	result = VerifyResponsePackage(RESPONSE, iGetData);
	return result;
}
